package com.example.multi.service.impl;

import com.example.multi.entity.DataResp;
import com.example.multi.entity.Order;
import com.example.multi.entity.User;
import com.example.multi.service.IOrderService;
import com.example.multi.service.ITestRequestService;
import com.example.multi.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

import java.util.List;
import java.util.concurrent.*;

@Service
public class TestRequestService implements ITestRequestService {

    @Autowired
    IUserService userService;
    @Autowired
    IOrderService orderService;

    /**
     * 自定义 - 线程池
     */
    private static final ThreadPoolExecutor executorService = new ThreadPoolExecutor(50, 200,
            180L, TimeUnit.SECONDS,
            new LinkedBlockingQueue<Runnable>(3000), new ThreadFactory() {

        final ThreadFactory defaultFactory = Executors.defaultThreadFactory();

        @Override
        public Thread newThread(Runnable r) {
            Thread thread = defaultFactory.newThread(r);
            thread.setName("testRequest - " + thread.getName());
            return thread;
        }
    }, new ThreadPoolExecutor.CallerRunsPolicy());


    /**
     * 聚合接口-串行获取数据
     * @return
     */
    @Override
    public DataResp getDateResp(){
        //获取用户列表
        List<User> userList = userService.listUser_1();
        //获取订单列表
        List<Order> orderList = orderService.listOrder_1();
        return DataResp.builder().userList(userList).orderList(orderList).build();
    };

    /**
     * 聚合接口-并行获取数据(@Async) 头信息 无法透传到子线程
     * @return
     */
    @Override
    public DataResp getDateResp2() throws ExecutionException, InterruptedException {
        //获取用户列表 start
        Future<List<User>> userListFuture = userService.listUser_2();

        List<User> userList = userListFuture.get();
        //获取用户列表 end

        //获取订单列表 start
        Future<List<Order>> orderListFuture = orderService.listOrder_2();
        List<Order> orderList = orderListFuture.get();
        //获取订单列表 end

        return DataResp.builder().userList(userListFuture.get()).orderList(orderList).build();
    };



    /**
     * 聚合接口-并行获取数据
     * @return
     */
    @Override
    public DataResp getDateResp3() throws ExecutionException, InterruptedException {
        RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
        //获取用户列表 start
        Future<List<User>> userListFuture = CompletableFuture.supplyAsync(() -> {
            RequestContextHolder.setRequestAttributes(attributes);
            try {
                List<User> resp = userService.listUser_3();
                return resp;
            }finally {
                RequestContextHolder.resetRequestAttributes();
            }
        }, executorService);

        List<User> userList = userListFuture.get();
        //获取用户列表 end

        //获取订单列表 start
        Future<List<Order>> orderListFuture = CompletableFuture.supplyAsync(() -> {
            RequestContextHolder.setRequestAttributes(attributes);
            try {
                List<Order> resp = orderService.listOrder_3();
                return resp;
            }finally {
                RequestContextHolder.resetRequestAttributes();
            }
        }, executorService);
        List<Order> orderList = orderListFuture.get();
        //获取订单列表 end

        return DataResp.builder().userList(userListFuture.get()).orderList(orderList).build();
    };


    /**
     * 聚合接口-并行获取数据(@Async) 头信息 能透传到子线程
     * @return
     */
    @Override
    public DataResp getDateResp4() throws ExecutionException, InterruptedException {
        //获取用户列表 start
        Future<List<User>> userListFuture = userService.listUser_4();

        List<User> userList = userListFuture.get();
        //获取用户列表 end

        //获取订单列表 start
        Future<List<Order>> orderListFuture = orderService.listOrder_4();
        List<Order> orderList = orderListFuture.get();
        //获取订单列表 end

        return DataResp.builder().userList(userListFuture.get()).orderList(orderList).build();
    };


}
